package fr.uparis10.miage.m1p1.core;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import fr.uparis10.miage.m1p1.global.UniqueIdManager;
import fr.uparis10.miage.classic.m1.p3.*;

public abstract class Employe {
	private final Integer codeEmploye;
	private String nom = "";
	private String prenom = "";
	private String adresse = "";
	private final long numSecu;
	protected float salaire;
	private Date dateNaissance;
	private final Date dateEmbauche;
	private Date dateRetraite;
	private Date dateDemmission;
	private Statut statut = Statut.ACTIVE;
	private String e_mail = "";
	private String num_telephone = "";
	protected PerformanceEmploye indice = PerformanceEmploye.C;
	private Integer codeDepatement;
	protected Departement departement;
	protected ArrayList<Projet> projetList = new ArrayList<Projet>();
	protected List<Employe> emList;

	/* Calcul du bonus, methode abstraite */

	public abstract int calcBonus();

	/* Constructeur sans param�tre de Employe */

	public Employe() {
		codeEmploye = UniqueIdManager.getInstance().createNewEmplId();
		numSecu = UniqueIdManager.getInstance().createNewNumSS();
		dateEmbauche = Calendar.getInstance().getTime();
	}

	/* Constructeur avec codeEmploye et numSecu en param�tres de Employe */

	public Employe(int preferedEmplId, long preferedNumSS) {
		codeEmploye = UniqueIdManager.getInstance().createNewEmplId(
				preferedEmplId);
		numSecu = UniqueIdManager.getInstance().createNewNumSS(preferedNumSS);
		dateEmbauche = Calendar.getInstance().getTime();
	}

	/*
	 * Constructeur avec codeEmploye et numSecu et dateEmbauche en param�tres de
	 * Employe
	 */

	public Employe(int preferedEmplId, long preferedNumSS, Date joinDate) {
		codeEmploye = UniqueIdManager.getInstance().createNewEmplId(
				preferedEmplId);
		numSecu = UniqueIdManager.getInstance().createNewNumSS(preferedNumSS);
		dateEmbauche = joinDate;
	}

	/* Affichage de tous les caract�ritiques d'un employ� */

	public String toString() {
		StringBuffer buf = new StringBuffer(" Code Employ\u00e9 : ");
		buf.append(codeEmploye);
		buf.append(";\nNum\u00e9ro de s\u00e9curit\u00e9 sociale: ");
		buf.append(numSecu);
		buf.append(";\nDate d'embauche: ");
		buf.append(dateEmbauche);
		buf.append(";\nNom: ");
		buf.append(nom);
		buf.append(";\nPrenom: ");
		buf.append(prenom);
		buf.append(";\nAdresse: ");
		buf.append(adresse);
		buf.append(";\nDate de naissance: ");
		buf.append(dateNaissance);
		buf.append(";\nNum\u00e9ro de t\u00e9l\u00e9phone: ");
		buf.append(num_telephone);
		buf.append(";\nAdresse \u00e9lectronique: ");
		buf.append(e_mail);
		buf.append(";\nStatut: ");
		buf.append(statut);
		buf.append(";\nD\u00e9partement: ");
		buf.append(departement == null ? "" : departement.getNom());
		buf.append(";\nSalaire: ");
		buf.append(salaire);
		buf.append(";\nIndicateur de Performance: ");
		buf.append(indice);
		buf.append(";\nGrade: ");
		buf.append(this.getClass().getSimpleName());
		buf.append(".\n");
		return buf.toString();
	}

	/* D�part en retraite d'un employe */

	public void partirRetraite() {
		this.setStatut(Statut.RETRAITE);
		Date date = new Date();
		this.dateRetraite = date;
		System.out.print(" D�part en r�traite de l'employ� :" + this.getNom()
				+ " " + " date de d�part :" + dateRetraite);
		System.out.print("\n");
		for (Projet projet : projetList) {
			if (projet.estaffecter(this))
				projet.desaffecterEmploye(this);
			System.out.print("\n");
		}
	}

	/* D�mmission d'un employ� */

	public void Demissioner() {
		this.setStatut(Statut.DEMISSIONNER);
		Date date = new Date();
		this.dateDemmission = date;
		System.out.print("D�mission de l'emply� :" + this.getNom() + " "
				+ " date de d�mission :" + dateDemmission);
		System.out.print("\n");
		for (Projet projet : projetList) {
			if (projet.estaffecter(this))
				projet.desaffecterEmploye(this);
		}
	}

	/* Changement de d�partement pour un employ� */

	public void changerDepartement(Departement newdept) {
		if (departement != null) {
			departement.removeEmploye(this);
		}
		departement = newdept;
		if (departement != null) {
			departement.addEmploye(this);
		}
	}

	/* Augmentation de salaire selon la note pour un employ� */

	public float augmenterSalaire() {
		PerformanceEmploye performance = this.indice;
		switch (performance) {
		case A:
			salaire += (salaire * 0.3);
			break;
		case B:
			salaire += (salaire * 0.2);
			break;
		case C:
			salaire += (salaire * 0.1);
			break;
		case D:
			salaire += (salaire * 0.05);
			break;
		case E:
			salaire += (salaire * 0.025);
			break;
		default:
			return salaire;

		}
		return salaire;

	}

	/* Affichage des projets auquels un employ� est affect� */

	public void afficherProjetEmploye() {
		System.out
				.println("la liste des projets auquels est affect\u00e9 cet employ\u00e9:");
		for (Projet pr : projetList)
			if (pr.estaffecter(this)) {
				System.out.println("Code Projet:" + " " + pr.getCodeProjet()
						+ " ," + "Th�me Projet:" + pr.getThemeProjet() + " ,"
						+ "Budjet du projet:" + pr.getBudjetProjet());
			}
	}

	public void ajouterEmploye() {
		if (!emList.contains(this))
			System.out.print("taille:" + emList.size());
		emList.add(this);
	}

	/* ajouter un projet � la liste des projets de l'employ� */

	public void ajouterProjet(Projet p) {
		if (!projetList.contains(p))
			projetList.add(p);
	}

	@Override
	public int hashCode() {
		int hash = 0;
		hash += (codeEmploye != null ? codeEmploye.hashCode() : 0);
		return hash;
	}

	/* Red�finition de la methode equals pour l'objet Employe */

	public boolean equals(Object object) {
		// TODO: Warning - this method won't work in the case the id fields are
		// not set
		if (!(object instanceof Employe)) {
			return false;
		}
		Employe other = (Employe) object;
		if ((this.codeEmploye == null && other.codeEmploye != null)
				|| (this.codeEmploye != null && !this.codeEmploye
						.equals(other.codeEmploye))) {
			return false;
		}
		return true;
	}

	/* Les getteurs & setteurs pour les attributs priv�s */

	public ArrayList<Projet> getProjetList() {
		return projetList;
	}

	public void setProjetList(ArrayList<Projet> projetList) {
		this.projetList = projetList;
	}

	public PerformanceEmploye getIndice() {
		return indice;
	}

	public void setIndice(PerformanceEmploye indice) {
		this.indice = indice;
	}

	public Departement getDepartement() {
		return departement;
	}

	public void setDepartement(Departement departement) {
		if (this.departement != null) {
			// remove the employee from old department list
			this.departement.removeEmploye(this);
		}
		this.departement = departement;
		if (this.departement != null) {
			// add the employee to the new department list
			this.departement.addEmploye(this);
		}
	}

	public Integer getCodeEmploye() {
		return codeEmploye;
	}

	public void setNom(String nom) {
		this.nom = nom;
	}

	public String getNom() {
		return nom;
	}

	public void setPrenom(String prenom) {
		this.prenom = prenom;
	}

	public String getPrenom() {
		return prenom;
	}

	public void setAdresse(String adresse) {
		this.adresse = adresse;
	}

	public String getAdresse() {
		return adresse;
	}

	public long getNumSecu() {
		return numSecu;
	}

	public void setSalaire(float salaire) {
		this.salaire = salaire;
	}

	public float getSalaire() {
		return salaire;
	}

	public Date getDateEmbauche() {
		return dateEmbauche;
	}

	public void setDateRetraite(Date dateRetraite) {
		this.dateRetraite = dateRetraite;
	}

	public Date getDateRetraite() {
		return dateRetraite;
	}

	public void setDateDemmission(Date dateDemmission) {
		this.dateDemmission = dateDemmission;
	}

	public Date getDateDemmission() {
		return dateDemmission;
	}

	public void setStatut(Statut statut) {
		this.statut = statut;
	}

	public Statut getStatut() {
		return statut;
	}

	public Date getDateNaissance() {
		return dateNaissance;
	}

	public void setDateNaissance(Date dateNaissance) {
		this.dateNaissance = dateNaissance;
	}

	public void setE_mail(String e_mail) {
		this.e_mail = e_mail;
	}

	public String getE_mail() {
		return e_mail;
	}

	public void setNum_telephone(String num_telephone) {
		this.num_telephone = num_telephone;
	}

	public String getNum_telephone() {
		return num_telephone;
	}

	public void setCodeDepatement(Integer codeDepatement) {
		this.codeDepatement = codeDepatement;
	}

	public Integer getCodeDepatement() {
		return codeDepatement;
	}

}
